﻿#ifndef CUSTOM_LIGHTING_INCLUDED
#define CUSTOM_LIGHTING_INCLUDED

#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"

float3 IncomingLight (Surface surface, Light light) {
	return
		saturate(dot(surface.normal, light.direction) * light.attenuation) *
		light.color;
}

float3 GetLighting (Surface surface, BRDF brdf, Light light) {
#if _SKIN
	return IncomingLight(surface, light) * DirectBRDF(surface, brdf, light)+LightScattering(surface, brdf, light) * light.color;
	//return SoftLight(IncomingLight(surface, light) * DirectBRDF(surface, brdf, light), LightScattering(surface, brdf, light));
	//return SoftLight(LightScattering(surface, brdf, light), IncomingLight(surface, light) * DirectBRDF(surface, brdf, light));
#elif _FABRIC
	return IncomingLight(surface, light) * DirectBRDF(surface, brdf, light)+FabricScattering(surface, brdf, light);
	//return FabricScattering(surface, brdf, light);
#else
	return IncomingLight(surface, light) * DirectBRDF(surface, brdf, light);
#endif
}

bool RenderingLayersOverlap (Surface surface, Light light) {
	return (surface.renderingLayerMask & light.renderingLayerMask) != 0;
}

float3 GetDirectLighting(Surface surfaceWS, BRDF brdf, ShadowData shadowData)
{
	float3 color = float3(0, 0, 0);
	for (int i = 0; i < GetDirectionalLightCount(); i++) {
		Light light = GetDirectionalLight(i, surfaceWS, shadowData);
		if (RenderingLayersOverlap(surfaceWS, light)) {
			color += GetLighting(surfaceWS, brdf, light);
		}
	}

#if defined(_LIGHTS_PER_OBJECT)
	for (int j = 0; j < min(unity_LightData.y, 8); j++) {
		int lightIndex = unity_LightIndices[(uint)j / 4][(uint)j % 4];
		Light light = GetOtherLight(lightIndex, surfaceWS, shadowData);
		if (RenderingLayersOverlap(surfaceWS, light)) {
			color += GetLighting(surfaceWS, brdf, light);
		}
	}
#else
	for (int j = 0; j < GetOtherLightCount(); j++) {
		Light light = GetOtherLight(j, surfaceWS, shadowData);
		if (RenderingLayersOverlap(surfaceWS, light)) {
			color += GetLighting(surfaceWS, brdf, light);
		}
	}
#endif
	return color;
}

float3 GetLighting (Surface surfaceWS, BRDF brdf, GI gi) {
	ShadowData shadowData = GetShadowData(surfaceWS);
	shadowData.shadowMask = gi.shadowMask;
	
	float3 color = IndirectBRDF(surfaceWS, brdf, gi.diffuse, gi.specular);

	color += GetDirectLighting(surfaceWS, brdf, shadowData);

	////float3 color;
	//for (int i = 0; i < GetDirectionalLightCount(); i++) {
	//	Light light = GetDirectionalLight(i, surfaceWS, shadowData);
	//	if (RenderingLayersOverlap(surfaceWS, light)) {
	//		color += GetLighting(surfaceWS, brdf, light);
	//	}
	//}
	//
	//#if defined(_LIGHTS_PER_OBJECT)
	//	for (int j = 0; j < min(unity_LightData.y, 8); j++) {
	//		int lightIndex = unity_LightIndices[(uint)j / 4][(uint)j % 4];
	//		Light light = GetOtherLight(lightIndex, surfaceWS, shadowData);
	//		if (RenderingLayersOverlap(surfaceWS, light)) {
	//			color += GetLighting(surfaceWS, brdf, light);
	//		}
	//	}
	//#else
	//	for (int j = 0; j < GetOtherLightCount(); j++) {
	//		Light light = GetOtherLight(j, surfaceWS, shadowData);
	//		if (RenderingLayersOverlap(surfaceWS, light)) {
	//			color += GetLighting(surfaceWS, brdf, light);
	//		}
	//	}
	//#endif


	return color;
}

float3 GetLighting(Surface surfaceWS, BRDF brdf, IBL ibl) 
{
	ShadowData shadowData = GetShadowData(surfaceWS);
	//shadowData.shadowMask = gi.shadowMask;

	//float3 color = IndirectBRDF(surfaceWS, brdf, ibl.diffuse, ibl.specular);

	//float3 color = float3(0, 0, 0);

	float3 color = (ibl.diffuse + ibl.specular)* surfaceWS.occlusion;

	//float3 color = ibl.diffuse;

	color += GetDirectLighting(surfaceWS, brdf, shadowData);


	return color;
}
#endif